﻿#define  _CRT_SECURE_NO_WARNINGS

#include<vector>
#include<assert.h>
#include<algorithm>
#include"list.h"
#include<list>

using namespace std;

//class Solution {
//public:
//	// 传值返回需要拷贝
//	string addStrings(string num1, string num2) {
//		string str;
//		int end1 = num1.size() - 1, end2 = num2.size() - 1;
//		// 进位
//		int next = 0;
//		while (end1 >= 0 || end2 >= 0)
//		{
//			int val1 = end1 >= 0 ? num1[end1--] - '0' : 0;
//			int val2 = end2 >= 0 ? num2[end2--] - '0' : 0;
//			int ret = val1 + val2 + next;
//			next = ret / 10;
//			ret = ret % 10;
//			str += ('0' + ret);
//		}
//		if (next == 1)
//			str += '1';
//		reverse(str.begin(), str.end());
//		return str;
//	}
//};
//
//class Solution {
//public:
//	// 这里的传值返回拷贝代价就太⼤了
//	vector<vector<int>> generate(int numRows) {
//		vector<vector<int>> vv(numRows);
//		for (int i = 0; i < numRows; ++i)
//		{
//			vv[i].resize(i + 1, 1);
//		}
//		for (int i = 2; i < numRows; ++i)
//		{
//			for (int j = 1; j < i; ++j)
//			{
//				vv[i][j] = vv[i - 1][j] + vv[i - 1][j - 1];
//			}
//		}
//		return vv;
//	}
//};

namespace bit
{
	class string
	{
	public:
		typedef char* iterator;
		typedef const char* const_iterator;

		iterator begin()
		{
			return _str;
		}

		iterator end()
		{
			return _str + _size;
		}

		const_iterator begin() const
		{
			return _str;
		}

		const_iterator end() const
		{
			return _str + _size;
		}

		string(const char* str = "")
			:_size(strlen(str))
			, _capacity(_size)
		{
			cout << "string(char* str)-构造" << endl;
			_str = new char[_capacity + 1];
			strcpy(_str, str);
		}

		void swap(string& s)
		{
			std::swap(_str, s._str);
			std::swap(_size, s._size);
			std::swap(_capacity, s._capacity);
		}

		// 拷贝构造
		string(const string& s)
			:_str(nullptr)
		{
			cout << "string(const string& s) -- 拷贝构造" << endl;
			reserve(s._capacity);
			for (auto ch : s)
			{
				push_back(ch);
			}
		}

		// 移动构造
		string(string&& s)
		{
			cout << "string(string&& s) -- 移动构造" << endl;
			this->swap(s);
		}

		string& operator=(const string& s)
		{
			cout << "string& operator=(const string& s) -- 拷贝赋值" << endl;
			if (this != &s)
			{
				_str[0] = '\0';
				_size = 0;
				reserve(s._capacity);
				for (auto ch : s)
				{
					push_back(ch);
				}
			}
			return *this;
		}

		// 移动赋值
		string& operator=(string&& s)
		{
			cout << "string& operator=(string&& s) -- 移动赋值" << endl;
			this->swap(s);
			return *this;
		}

		~string()
		{
			cout << "~string() -- 析构" << endl;
			delete[] _str;
			_str = nullptr;
		}

		char& operator[](size_t pos)
		{
			assert(pos < _size);
			return _str[pos];
		}

		void reserve(size_t n)
		{
			if (n > _capacity)
			{
				char* tmp = new char[n + 1];
				if (_str)
				{
					strcpy(tmp, _str);
					delete[] _str;
				}
				_str = tmp;
				_capacity = n;
			}
		}

		void push_back(char ch)
		{
			if (_size >= _capacity)
			{
				size_t newcapacity = _capacity == 0 ? 4 : _capacity * 2;
				reserve(newcapacity);
			}
			_str[_size] = ch;
			++_size;
			_str[_size] = '\0';
		}

		string& operator+=(char ch)
		{
			push_back(ch);
			return *this;
		}

		const char* c_str() const
		{
			return _str;
		}

		size_t size() const
		{
			return _size;
		}
	private:
		char* _str = nullptr;
		size_t _size = 0;
		size_t _capacity = 0;
	};

	string addStrings(string num1, string num2)
	{
		string str;
		int end1 = num1.size() - 1, end2 = num2.size() - 1;
		int next = 0;
		while (end1 >= 0 || end2 >= 0)
		{
			int val1 = end1 >= 0 ? num1[end1--] - '0' : 0;
			int val2 = end2 >= 0 ? num2[end2--] - '0' : 0;
			int ret = val1 + val2 + next;
			next = ret / 10;
			ret = ret % 10;
			str += ('0' + ret);
		}
		if (next == 1)
			str += '1';
		reverse(str.begin(), str.end());
		cout << "******************************" << endl;
		// vs2019及以后将str优化为ret的引用
		return str;
	}
}

//// 由于引用折叠限定，f1实例化以后总是⼀个左值引用
//template<class T>
//void f1(T& x)
//{}
//
//// 由于引用折叠限定，f2实例化后可以是左值引用，也可以是右值引用
//template<class T>
//void f2(T&& x)
//{}
//
//int main()
//{
//	typedef int& lref;
//	typedef int&& rref;
//	int n = 0;
//	lref& r1 = n; // r1 的类型是 int&
//	lref&& r2 = n; // r2 的类型是 int&
//	rref& r3 = n; // r3 的类型是 int&
//	rref&& r4 = 1; // r4 的类型是 int&&
//
//	// 没有折叠->实例化为void f1(int& x)
//	f1<int>(n);
//	//f1<int>(0); // 报错
//	// 折叠->实例化为void f1(int& x)
//	f1<int&>(n);
//	//f1<int&>(0); // 报错
//	// 折叠->实例化为void f1(int& x)
//	f1<int&&>(n);
//	//f1<int&&>(0); // 报错
//	// 折叠->实例化为void f1(const int& x)
//	f1<const int&>(n);
//	f1<const int&>(0);
//	// 折叠->实例化为void f1(const int& x)
//	f1<const int&&>(n);
//	f1<const int&&>(0);
//	// 没有折叠->实例化为void f2(int&& x)
//	//f2<int>(n); // 报错
//	f2<int>(0);
//	// 折叠->实例化为void f2(int& x)
//	f2<int&>(n);
//	//f2<int&>(0); // 报错
//	// 折叠->实例化为void f2(int&& x)
//	//f2<int&&>(n); // 报错
//	f2<int&&>(0);
//	return 0;
//}

//int main()
//{
//	bit::list<bit::string> lt;
//	bit::string s1("111111111111111111111");
//	lt.push_back(s1);
//	cout << "*************************" << endl;
//	lt.push_back(bit::string("22222222222222222222222222222"));
//	cout << "*************************" << endl;
//	lt.push_back("3333333333333333333333333333");
//	cout << "*************************" << endl;
//	lt.push_back(move(s1));
//	cout << "*************************" << endl;
//	return 0;
//}

// 场景
//int main()
//{
//	//bit::string ret = bit::addStrings("11111", "2222");
//
//	bit::string ret;
//	ret = bit::addStrings("11111", "2222");
//
//	return 0;
//}

//int main()
//{
//	my_string::string s1("xxxxxxx");
//	// 拷贝构造
//	my_string::string s2 = s1;
//	// 构造+移动构造，优化后直接构造
//	my_string::string s3 = my_string::string("yyyyy");
//	// 移动构造
//	my_string::string s4 = move(s1);
//	// 移动赋值
//	s4 = my_string::string("zzzzzzzzz");
//	cout << "******************************" << endl;
//	return 0;
//}

//// 引用折叠 -> 万能引用
//template<class T>
//void Function(T&& t)
//{
//	int a = 0;
//	T x = a;
//	/*x++;*/
//	cout << &a << endl;
//	cout << &x << endl << endl;
//}
//
//int main()
//{
//	//// 10是右值，推导出T为int，模板实例化为void Function(int&& t)
//	//Function(10); // 右值
//	int a;
//	//// a是左值，推导出T为int&，引用折叠，模板实例化为void Function(int& t)
//	//Function(a); // 左值
//	//// std::move(a)是右值，推导出T为int，模板实例化为void Function(int&& t)
//	//Function(std::move(a)); // 右值
//	const int b = 8;
//	//// a是左值，推导出T为const int&，引⽤折叠，模板实例化为void Function(const int& t)
//	//// 所以Function内部会编译报错，x不能++
//	//Function(b); // const 左值
//	// std::move(b)右值，推导出T为const int，模板实例化为void Function(const int&& t)
//	// 所以Function内部会编译报错，x不能++
//	Function(std::move(b)); // const 右值
//	return 0;
//}

//void Fun(int& x) { cout << "左值引用" << endl; }
//void Fun(const int& x) { cout << "const 左值引用" << endl; }
//void Fun(int&& x) { cout << "右值引用" << endl; }
//void Fun(const int&& x) { cout << "const 右值引用" << endl; }
//
//template<class T>
//void Function(T&& t)
//{
//	//Fun(t);
//	Fun(forward<T>(t));
//}
//
//int main()
//{
//	// 10是右值，推导出T为int，模板实例化为void Function(int&& t)
//	Function(10); // 右值
//	int a;
//	// a是左值，推导出T为int&，引⽤折叠，模板实例化为void Function(int& t)
//	Function(a); // 左值
//	// std::move(a)是右值，推导出T为int，模板实例化为void Function(int&& t)
//	Function(std::move(a)); // 右值
//	const int b = 8;
//	// a是左值，推导出T为const int&，引⽤折叠，模板实例化为void Function(const int&	t)
//	Function(b); // const 左值
//	// std::move(b)右值，推导出T为const int，模板实例化为void Function(const int&&	t)
//	Function(std::move(b)); // const 右值
//	return 0;
//}

//template<class ...Args>
//void Print(Args&&... args)
//{
//	cout << sizeof...(args) << endl;
//}

// 编译时完成
//void Print(double&& x1, string&& x2, double&& x3)
//{
//	cout << 3 << endl;
//}

// 包扩展1
// 编译时递归推导解析参数
//void showlist()
//{
//	cout << endl;
//}
//
//template<class T, class ...Args>
//void showlist(T x, Args... args)
//{
//	cout << x << " ";
//	showlist(args...);
//}

// 底层
//void showlist()
//{
//	cout << endl;
//}
//
//void showlist(int x3)
//{
//	cout << x3 << " ";
//	showlist();
//}
//
//void showlist(string x2, int x3)
//{
//	cout << x2 << " ";
//	showlist(x3);
//}
//
//void showlist(double x1, string x2, int x3)
//{
//	cout << x1 << " ";
//	showlist(x2, x3);
//}
//
//template<class ...Args>
//void Print(Args... args)
//{
//	showlist(args...);
//}

// 包扩展2
//template <class T>
//const T& GetArg(const T& x)
//{
//	cout << x << " ";
//	return x;
//}
//
//template <class ...Args>
//void Arguments(Args... args)
//{}
//
//template <class ...Args>
//void Print(Args... args)
//{
//	// 注意GetArg必须返回或者到的对象，这样才能组成参数包给Arguments
//	Arguments(GetArg(args)...); 
//}
//
//// 底层，编译时推导
////void Print(double x1, string x2, int x3)
////{
////	Arguments(GetArg(x1), GetArg(x2), GetArg(x3));
////}
//
//int main()
//{
//	Print(1.1, string("xxxxx"), 1); // 包里有3个参数
//	return 0;
//}

// emplace系列
// emplace_back总体而言是更高效，推荐以后使用emplace系列替代insert和push系列
//int main()
//{
//	bit::list<bit::string> lt;
//	// 传左值，拷贝构造，两者效率一样
//	bit::string s1 = "xxxxxxxx";
//	lt.push_back(s1);
//	lt.emplace_back(s1);
//	cout << "**************************************" << endl;
//	// 传右值，移动构造，两者效率一样
//	bit::string s2 = "22222222222";
//	lt.push_back(move(s2));
//	bit::string s3 = "22222222222";
//	lt.emplace_back(move(s3));
//	cout << "**************************************" << endl;
//	// emplace略胜一筹
//	lt.push_back("111111111111111");		// push_back在类模板实例化时实例化，const char*->string，需要拷贝/移动
//	lt.emplace_back("111111111111111");		// emplace_back在传参时实例化，为函数模板，const char*可直接构造
//	cout << "**************************************" << endl;
//	bit::list<pair<bit::string, int>> lt1;
//	pair<bit::string, int> kv1 = { "hajimi", 666 };
//	lt1.push_back(kv1);
//	lt1.emplace_back(kv1);
//	cout << "**************************************" << endl;
//	pair<bit::string, int> kv2 = { "dgj", 666 };
//	lt1.push_back(move(kv2));
//	pair<bit::string, int> kv3 = { "ddj", 666 };
//	lt1.emplace_back(move(kv3));
//	cout << "**************************************" << endl;
//	lt1.push_back({ "hajimi", 1 });
//	// 直接把构造pair参数包往下传，直接用pair参数包构造pair
//	//lt1.emplace_back({ "hajimi", 1 }); // 不支持
//	lt1.emplace_back("hajimi", 666);
//	cout << "**************************************" << endl;
//
//	return 0;
//}

//class Person
//{
//public:
//	Person(const char* name = "张三", int age = 1)
//		:_name(name)
//		, _age(age)
//		, _i(11)
//	{}
//
//	// 委托构造
//	Person(int i, const char* name = "张三", int age = 1)
//		:Person(name, age)
//	{
//		_i = i;
//	}
//
//	// 强制不让生成，不期望这个类的对象被拷贝
//	//Person(const Person& p) = delete;
//
//	/*Person(const Person& p)
//		:_name(p._name)
//		,_age(p._age)
//	{}*/
//
//	// 强制生成
//	//Person(Person&& p) = default;
//
//	/*Person& operator=(const Person& p)
//	{
//		if(this != &p)
//		{
//			_name = p._name;
//			_age = p._age;
//		}
//		return *this;
//	}*/
//
//	/*~Person()
//	{}*/
//
//private:
//	bit::string _name;
//	int _age;
//	int _i = 0;
//};
//
//int main()
//{
//	Person s1;
//	Person s2 = s1;			   // 拷贝构造
//	Person s3 = std::move(s1); // 移动构造
//	/*Person s4;
//	s4 = std::move(s2);*/
//
//	return 0;
//}

// lambda
//int main()
//{
//	auto add = [](int a, int b)->int { return a + b; };
//	cout << add(1, 2) << endl;
//
//	// 1、捕捉为空也不能省略
//	// 2、参数为空可以省略
//	// 3、返回值可以省略，可以通过返回对象⾃动推导
//	// 4、函数体不能省略
//	auto func1 = []
//	{
//		cout << "hello lambda" << endl;
//		return 0;
//	};
//	func1();
//
//
//
//	return 0;
//}

//int x = 0;
////// 捕捉列表必须为空，因为全局变量不用捕捉就可以用，没有可被捕捉的变量
////auto func1 = []()
////{
////	x++;
////};
//
//int main()
//{
//	int a = 0, b = 1, c = 2, d = 3;
//	auto func1 = [a, &b]
//	{
//		//a++;
//		b++;
//		int ret = a + b;
//		return ret;
//	};
//	cout << func1() << endl;
//	cout << a << " " << b << " " << c << " " << d << endl;
//
//	// 隐式值捕捉
//	// 用了哪些变量就捕捉哪些变量
//	auto func2 = [=] 
//	{
//		int ret = a + b + c;
//		return ret;
//	};
//	cout << func2() << endl;
//
//	auto func3 = [&]
//	{
//		a++;
//		c++;
//		d++;
//	};
//	func3();
//	cout << a << " " << b << " " << c << " " << d << endl;
//
//	// 混合捕捉1
//	auto func4 = [&, a, b] 
//	{
//		//a++;
//		//b++;
//		c++;
//		d++; 
//	};
//	func4();
//	cout << a << " " << b << " " << c << " " << d << endl;
//
//	// 混合捕捉2
//	auto func5 = [=, &a, &b]
//	{
//		a++;
//		b++;
//		/*c++;
//		d++;*/
//	};
//	func5();
//	cout << a << " " << b << " " << c << " " << d << endl;
//
//	// 局部的静态和全局变量不能捕捉，也不需要捕捉
//	static int m = 1;
//	auto func6 = []
//	{
//		int ret = x + m;
//		return ret;
//	};
//	cout << func6() << endl;
//
//	// 传值捕捉本质是一种拷贝,并且被const修饰了
//	// mutable相当于去掉const属性，可以修改了
//	// 但是修改了不会影响外面被捕捉的值，因为是一种拷贝
//	auto func7 = [=]() mutable
//	{
//		a++;
//		b++;
//		c++;
//		d++;
//		return a + b + c + d;
//	};
//	cout << func7() << endl;
//	cout << a << " " << b << " " << c << " " << d << endl;
//
//
//	return 0;
//}

struct Goods
{
	string _name; // 名字
	double _price; // 价格
	int _evaluate; // 评价
	// ...
	Goods(const char* str, double price, int evaluate)
		:_name(str)
		, _price(price)
		, _evaluate(evaluate)
	{}
};

struct ComparePriceLess
{
	bool operator()(const Goods& gl, const Goods& gr)
	{
		return gl._price < gr._price;
	}
};

struct ComparePriceGreater
{
	bool operator()(const Goods& gl, const Goods& gr)
	{
		return gl._price > gr._price;
	}
};

//int main()
//{
//	vector<Goods> v = { { "苹果", 2.1, 5 }, { "香蕉", 3, 4 }, { "橙子", 2.2, 3 }, { "菠萝", 1.5, 4 } };
//
//	// 类似这样的场景，我们实现仿函数对象或者函数指支持商品中
//	// 不同项的比较，相对还比较麻烦的，那么这里lambda就很好用了
//	//sort(v.begin(), v.end(), ComparePriceLess());
//	//sort(v.begin(), v.end(), ComparePriceGreater());
//
//	sort(v.begin(), v.end(), [](const Goods& gl, const Goods& gr) {
//		return gl._price < gr._price;
//		});
//
//	sort(v.begin(), v.end(), [](const Goods& gl, const Goods& gr) {
//		return gl._price > gr._price;
//		});
//
//	sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2) {
//		return g1._evaluate < g2._evaluate;
//		});
//
//	sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2) {
//		return g1._evaluate > g2._evaluate;
//		});
//
//	return 0;
//}

//class Rate
//{
//public:
//	Rate(double rate)
//		: _rate(rate)
//	{}
//	double operator()(double money, int year)
//	{
//		return money * _rate * year;
//	}
//private:
//	double _rate;
//};
//
//int main()
//{
//	double rate = 0.49;
//
//	// lambda
//	auto r2 = [rate](double money, int year) {
//		return money * rate * year;
//		};
//
//	// 函数对象
//	Rate r1(rate);
//	r1(10000, 2);
//	r2(10000, 2);
//
//	auto func1 = [] {
//		cout << "hello world" << endl;
//		};
//	func1();
//
//	return 0;
//}

// 包装器function
// 类模板
//template <class T>
//class function; // undefined
//
//template <class Ret, class... Args>
//class function<Ret(Args...)>;

//#include<functional>
//
//int f(int a, int b)
//{
//	return a + b;
//}
//
//struct Functor
//{
//public:
//	int operator() (int a, int b)
//	{
//		return (a + b) * 10;
//	}
//};
//
//class Plus
//{
//public:
//	Plus(int n = 10)
//		:_n(n)
//	{}
//
//	static int plusi(int a, int b)
//	{
//		return (a + b) * 10;
//	}
//
//	double plusd(double a, double b)
//	{
//		return (a + b) * _n;
//	}
//private:
//	int _n;
//};
//
//int main()
//{
//	function<int(int, int)> f1 = f;
//	//function<int(int, int)> f2(Functor());
//	function<int(int, int)> f2 = Functor();
//	function<int(int, int)> f3 = [](int a, int b) { return a + b * 10; };
//	
//	cout << f1(1, 1) << endl;
//	cout << f2(1, 1) << endl;
//	cout << f3(1, 1) << endl;
//
//	// 包装静态成员函数
//	// 成员函数要指定类域并且前面加&才能获取地址
//	function<int(int, int)> f4 = &Plus::plusi;
//	cout << f4(1, 1) << endl;
//
//	// 包装普通成员函数
//	// 普通成员函数还有一个隐含的this指针参数，所以绑定时传对象或者对象的指针过去都可以
//	function<double(Plus*, double, double)> f5 = &Plus::plusd;
//	Plus ps;
//	cout << f5(&ps, 1.1, 1.1) << endl;
//
//	function<double(Plus, double, double)> f6 = &Plus::plusd;
//	cout << f6(ps, 1.1, 1.1) << endl;
//
//	function<double(Plus&&, double, double)> f7 = &Plus::plusd;
//	cout << f7(move(ps), 1.1, 1.1) << endl;
//	cout << f7(Plus(), 1.1, 1.1) << endl;
//
//
//	return 0;
//}

// bind
#include<functional>

using placeholders::_1;
using placeholders::_2;
using placeholders::_3;

int Sub(int a, int b)
{
	return (a - b) * 10;
}

int SubX(int a, int b, int c)
{
	return (a - b - c) * 10;
}

class Plus
{
public:
	static int plusi(int a, int b)
	{
		return a + b;
	}

	double plusd(double a, double b)
	{
		return a + b;
	}
};

int main()
{
	auto sub1 = bind(Sub, _1, _2);
	cout << sub1(1, -1) << endl;

	// bind 本质返回的一个仿函数对象
	// 调整参数顺序（不常用）
	// _1代表第一个实参
	// _2代表第二个实参
	// ...

	auto sub2 = bind(Sub, _2, _1);
	cout << sub2(1, -1) << endl;

	// 调整参数个数 （常用）
	auto sub3 = bind(Sub, 100, _1);
	cout << sub3(-1) << endl;

	auto sub4 = bind(Sub, _1, 100);
	cout << sub4(-1) << endl;

	// 分别绑死第123个参数
	auto sub5 = bind(SubX, 100, _1, _2);
	cout << sub5(5, 1) << endl;
	auto sub6 = bind(SubX, _1, 100, _2);
	cout << sub6(5, 1) << endl;
	auto sub7 = bind(SubX, _1, _2, 100);
	cout << sub7(5, 1) << endl;

	// 成员函数对象进行绑死，就不需要每次都传递了
	function<double(Plus&&, double, double)> f6 = &Plus::plusd;
	Plus pd;
	cout << f6(move(pd), 1.1, 1.1) << endl;
	cout << f6(Plus(), 1.1, 1.1) << endl;

	//auto f7 = bind(&Plus::plusd, Plus(), _1, _2);
	function<double(double, double)> f7 = bind(&Plus::plusd, Plus(), _1, _2);
	cout << f7(1.1, 1.1) << endl;
	cout << f7(1.1, 1.1) << endl;

	// 计算复利的lambda
	auto func1 = [](double rate, double money, int year)->double {
		double ret = money;
		for (int i = 0; i < year; i++)
		{
			ret += ret * rate;
		}
		return ret - money;
	};

	// 绑死一些参数，实现出支持不同年华利率，不同金额和不同年份计算出复利的结算利息
	function<double(double)> func3_1_5 = bind(func1, 0.015, _1, 3);
	function<double(double)> func5_1_5 = bind(func1, 0.015, _1, 5);
	function<double(double)> func10_2_5 = bind(func1, 0.025, _1, 10);
	function<double(double)> func20_3_5 = bind(func1, 0.035, _1, 30);

	cout << func3_1_5(1000000) << endl;
	cout << func5_1_5(1000000) << endl;
	cout << func10_2_5(1000000) << endl;
	cout << func20_3_5(1000000) << endl;
	return 0;
}